package asteroids.model.programs.unaryexpression;

import asteroids.model.programs.*;
import be.kuleuven.cs.som.annotate.*;
import exception.IllegalOperandException;

@SuppressWarnings("all")
public abstract class UnaryExpression<T> extends ComposedExpression<T> {

	/**
	 * Initialize this new unary expression with given operand.
	 *
	 * @param  operand
	 *         The operand for this new unary expression.
	 * @post   The operand for this new unary expression is the
	 *         same as the given operand.
	 *       | new.getOperand() == operand
	 * @throws IllegalOperandException
	 *         This new unary expression cannot have the given
	 *         operand as its operand at index 1.
	 *       | ! canHaveAsOperandAt(operand,1)
	 */
	@Model
	protected UnaryExpression(Expression operand)
			throws IllegalOperandException {
		if (!canHaveAsOperandAt(operand,1))
			throw new IllegalOperandException(this, operand);
		setOperandAt(1, operand);
	}

	/**
	 * Return the number of operands involved in this unary expression.
	 *
	 * @return A unary expression always involves a single operand.
	 *       | result == 1
	 */
	@Override
	@Basic
	public final int getNbOperands() {
		return 1;
	}

	/**
	 * Return the operand of this unary expression at the given index.
	 * 
	 * @return The one and only operand of this unary expression.
	 *       | result == getOperand()
	 */
	@Override
	public final Expression getOperandAt(int index)
			throws IndexOutOfBoundsException {
		if (index != 1)
			throw new IndexOutOfBoundsException();
		return getOperand();
	}

	/**
	 * Return the operand of this unary expression.
	 */
	@Basic
	public Expression getOperand() {
		return operand;
	}
	
	/**
	 * Check whether this unary expression can have the given
	 * expression as its operand at the given index.
	 *
	 * @return True if and only if the given expression is effective,
	 *         and if that expression does not have this composed
	 *         expression as a subexpression, and if the given
	 *         index is 1.
	 *       | result ==
	 *       |    ( (expression != null) &&
	 *       |      (! expression.hasAsSubExpression(this)) &&
	 *       |      (index == 1) )
	 */
	@Override
	public boolean canHaveAsOperandAt(Expression expression, int index) {
		return super.canHaveAsOperandAt(expression, index) && (index == 1);
	}

	/**
	 * Set the operand for this unary expression at the given
	 * index to the given operand.
	 */
	@Override
	protected void setOperandAt(int index, Expression<T> operand) {
		this.operand = operand;
	}

	/**
	 * Variable referencing the operand of this unary expression.
	 * 
	 * @note    This variable is not qualified final, such that operands
	 *          can be changed in cloning unary expressions.
	 */
	private Expression operand;

}

